package netty.session;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.netty.channel.Channel;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class SessionManager {
    private StringRedisTemplate redisTemplate;
    private ObjectMapper mapper;
    private String localServerId;
    private NettySessionStore<String, NettySession> localSession;

    public SessionManager(StringRedisTemplate redisTemplate, String localServerId) {
        this.redisTemplate = redisTemplate;
        this.localServerId = localServerId;
        this.mapper = new ObjectMapper();
        this.localSession = new NettySessionStore<>(600, null);
    }

    public NettySession addSession(String sessionId, Channel channel) {
        NettySession s = new NettySession(sessionId, channel, localServerId);
        try {
            redisTemplate.opsForValue().set(sessionId, mapper.writeValueAsString(s), 48, TimeUnit.HOURS); // 这里假定48小时内，设备一定会离线
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        localSession.put(sessionId, s);
        return s;
    }

    public NettySession getSession(String sessionId) {
        String val = redisTemplate.opsForValue().get(sessionId);
        if (val != null) {
            try {
                NettySession session = mapper.readValue(val, NettySession.class);
                if (session != null) {
                    if (localServerId.equals(session.getServerId())) {
                        return localSession.get(sessionId);
                    } else {
                        return session;
                    }
                }
            } catch (IOException e) {
                return null;
            }
        }
        return null;
    }

    public void removeSession(String sessionId) {
        localSession.remove(sessionId);
//        redisTemplate.delete(sessionId); 只移除本地Session，其它主机可能已经更新redis上的session信息
    }

    public String getLocalServerId() {
        return localServerId;
    }
}
